package load_balance

import "errors"

type WeightNode struct {
	addr            string
	weight          int
	currentWeight   int
	effectiveWeight int
	totalWeight     int
}

/**
权重轮询负载均衡
*/
type WeightRoundRobinBalance struct {
	curIndex int
	rss      []*WeightNode
}

func (rb *WeightRoundRobinBalance) Add(nodes ...*WeightNode) error {
	if len(nodes) == 0 {
		return errors.New("params len 1 at least")
	}

	rb.rss = append(rb.rss, nodes...)

	return nil
}

func (rb *WeightRoundRobinBalance) Next() string {
	if len(rb.rss) == 0 {
		return ""
	}

	total := 0
	var best *WeightNode
	for i, max := 0, len(rb.rss); i < max; i++ {
		w := rb.rss[i]
		// 1、统计有效权重之和
		total += w.effectiveWeight
		// 2、变更节点临时权重为节点的临时权重+节点的有效权重
		w.currentWeight += w.effectiveWeight
		// 3、如果有效权重小于默认权重
		if w.effectiveWeight < w.weight {
			w.effectiveWeight++
		}
		//4、选择临时权重最大
		if best == nil || best.currentWeight < w.currentWeight {
			best = w
		}
	}

	best.currentWeight -= total

	return best.addr
}
